﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wormhole.Engine.Turn
{
	/// <author>Rodney McKay</author>
	/// <date>14 April 2008</date>
	/// <summary>
	/// Represent the phases in the game.
	/// </summary>
	public class GamePhases : List<GamePhase>
	{
		#region Delegates
		/// <summary>
		/// The delegate for the event that is raised when a new game phase is started.
		/// </summary>
		/// <param name="phase">The game phase that was started.</param>
		public delegate void PhaseStartDelegate(GamePhase phase);
		#endregion

		#region Events
		/// <summary>
		/// This event is raised when a new phase starts.
		/// </summary>
		public event PhaseStartDelegate PhaseStart;
		#endregion

		#region Properties

		#region Current Phase Index
		/// <summary>
		/// The index of the current phase.
		/// </summary>
		private int CurrentPhaseIndex { get; set; }
		#endregion

		#region Current Phase
		/// <summary>
		/// Get the current game phase.
		/// </summary>
		public GamePhase CurrentPhase
		{
			get
			{
				return this[this.CurrentPhaseIndex];
			}
		}
		#endregion

		#endregion

		#region Constructor
		/// <summary>
		/// Initialize a default instance of the class.
		/// </summary>
		public GamePhases()
		{
			this.InitialzeGamePhases();
		}
		#endregion

		#region Initialize Game Phases
		/// <summary>
		/// create the phases in a turn.
		/// </summary>
		protected void InitialzeGamePhases()
		{
			this.Add(Phase.Power);
			this.Add(Phase.Mission);
			this.Add(Phase.PerformAction);
			this.Add(Phase.ResolveMission);
			this.Add(Phase.DecideContinue);
			this.Add(Phase.Debrief);
			this.Add(Phase.EndOfTurn);
		}
		#endregion

		#region Index Of
		/// <summary>
		/// Find the index of a specific phase.
		/// </summary>
		/// <param name="phase">The phase to find.</param>
		/// <returns>The index of the phase.</returns>
		private int IndexOf(Phase phase)
		{
			foreach (GamePhase gamePhase in this)
			{
				if (gamePhase.PhaseType == phase)
					return this.IndexOf(gamePhase);
			}

			throw new IndexOutOfRangeException();
		}
		#endregion

		#region Add
		/// <summary>
		/// Add a new game phase.
		/// </summary>
		/// <param name="phase">The phase type.</param>
		/// <returns>Returns the game phase that was created.</returns>
		protected GamePhase Add(Phase phase)
		{
			// create the phase object
			GamePhase gamePhase = new GamePhase();
			gamePhase.PhaseType = phase;

			// add to the collection
			this.Add(gamePhase);

			// return the result
			return gamePhase;
		}
		#endregion

		#region Start Turn
		/// <summary>
		/// Start at the first phase.
		/// </summary>
		public void StartTurn()
		{
			this.CurrentPhaseIndex = 0;
			this.OnPhaseStart(this.CurrentPhase);
		}
		#endregion

		#region Next Phase
		/// <summary>
		/// Proceed to the next phase.
		/// </summary>
		public void NextPhase()
		{
			if (this.CurrentPhaseIndex < this.Count - 1)
			{
				this.CurrentPhaseIndex++;
				this.OnPhaseStart(this.CurrentPhase);
			}
		}
		#endregion

		#region On Phase Start
		/// <summary>
		/// Raise the phase start event.
		/// </summary>
		/// <param name="phase">The phase that was started.</param>
		protected void OnPhaseStart(GamePhase phase)
		{
			if (this.PhaseStart != null)
				this.PhaseStart(phase);
		}
		#endregion

		#region Go to Phase
		/// <summary>
		/// Go to a specific phase.
		/// </summary>
		/// <param name="phase">The phase to jump to.</param>
		public void GotoPhase(Phase phase)
		{
			this.CurrentPhaseIndex = this.IndexOf(phase);
			this.OnPhaseStart(this.CurrentPhase);
		}
		#endregion
	}
}
